/* Implemented from g_str_hash() */
static guint32
-gtk_compose_table_data_hash (gconstpointer v, int length)
+data_hash (gconstpointer v, int length)
{
const guint16 *p, *head;
unsigned char c;
return h;
}
+guint32
+gtk_compose_table_data_hash (const guint16 *data,
+ int max_seq_len,
+ int n_seqs)
+{
+ gsize n_index_stride;
+ gsize length;
+
+ n_index_stride = max_seq_len + 2;
+ if (!g_size_checked_mul (&length, n_index_stride, n_seqs))
+ {
+ g_critical ("Overflow in the compose sequences");
+ return 0;
+ }
+
+ return data_hash (data, length);
+}
+
static char *
gtk_compose_hash_get_cache_path (guint32 hash)
{
return contents;
}
-static int
-gtk_compose_table_find (gconstpointer data1,
- gconstpointer data2)
-{
- const GtkComposeTable *compose_table = (const GtkComposeTable *) data1;
- guint32 hash = (guint32) GPOINTER_TO_INT (data2);
- return compose_table->id != hash;
-}
-
static GtkComposeTable *
gtk_compose_table_load_cache (const char *compose_file)
{
g_assert (compose_file != NULL);
+ compose_table = gtk_compose_table_load_cache (compose_file);
+ if (compose_table != NULL)
+ return compose_table;
+
compose_list = gtk_compose_list_parse_file (compose_file);
if (compose_list == NULL)
return NULL;
max_compose_len,
n_index_stride,
g_str_hash (compose_file));
+
g_list_free_full (compose_list, (GDestroyNotify) gtk_compose_list_element_free);
+
+ gtk_compose_table_save_cache (compose_table);
+
return compose_table;
}
-GSList *
-gtk_compose_table_list_add_array (GSList *compose_tables,
- const guint16 *data,
- int max_seq_len,
- int n_seqs)
+GtkComposeTable *
+gtk_compose_table_new_with_data (const guint16 *data,
+ int max_seq_len,
+ int n_seqs)
{
- guint32 hash;
GtkComposeTable *compose_table;
gsize n_index_stride;
gsize length;
int i;
guint16 *gtk_compose_seqs = NULL;
- g_return_val_if_fail (data != NULL, compose_tables);
- g_return_val_if_fail (max_seq_len >= 0, compose_tables);
- g_return_val_if_fail (n_seqs >= 0, compose_tables);
+ g_return_val_if_fail (data != NULL, NULL);
+ g_return_val_if_fail (max_seq_len >= 0, NULL);
+ g_return_val_if_fail (n_seqs >= 0, NULL);
n_index_stride = max_seq_len + 2;
if (!g_size_checked_mul (&length, n_index_stride, n_seqs))
{
g_critical ("Overflow in the compose sequences");
- return compose_tables;
+ return NULL;
}
- hash = gtk_compose_table_data_hash (data, length);
-
- if (g_slist_find_custom (compose_tables, GINT_TO_POINTER (hash), gtk_compose_table_find) != NULL)
- return compose_tables;
-
gtk_compose_seqs = g_new0 (guint16, length);
for (i = 0; i < length; i++)
gtk_compose_seqs[i] = data[i];
compose_table->data = gtk_compose_seqs;
compose_table->max_seq_len = max_seq_len;
compose_table->n_seqs = n_seqs;
- compose_table->id = hash;
+ compose_table->id = data_hash (data, length);
compose_table->char_data = NULL;
compose_table->n_chars = 0;
- return g_slist_prepend (compose_tables, compose_table);
-}
-
-GSList *
-gtk_compose_table_list_add_file (GSList *compose_tables,
- const char *compose_file)
-{
- guint32 hash;
- GtkComposeTable *compose_table;
-
- g_return_val_if_fail (compose_file != NULL, compose_tables);
-
- hash = g_str_hash (compose_file);
- if (g_slist_find_custom (compose_tables, GINT_TO_POINTER (hash), gtk_compose_table_find) != NULL)
- return compose_tables;
-
- compose_table = gtk_compose_table_load_cache (compose_file);
- if (compose_table != NULL)
- return g_slist_prepend (compose_tables, compose_table);
-
- if ((compose_table = gtk_compose_table_new_with_file (compose_file)) == NULL)
- return compose_tables;
-
- gtk_compose_table_save_cache (compose_table);
- return g_slist_prepend (compose_tables, compose_table);
+ return compose_table;
}
static int
};
GtkComposeTable * gtk_compose_table_new_with_file (const char *compose_file);
-GSList * gtk_compose_table_list_add_array (GSList *compose_tables,
- const guint16 *data,
+GtkComposeTable * gtk_compose_table_new_with_data (const guint16 *data,
int max_seq_len,
int n_seqs);
-GSList * gtk_compose_table_list_add_file (GSList *compose_tables,
- const char *compose_file);
gboolean gtk_compose_table_check (const GtkComposeTable *table,
const guint16 *compose_buffer,
int n_compose,
gunichar *output);
+guint32 gtk_compose_table_data_hash (const guint16 *data,
+ int max_seq_len,
+ int n_seqs);
G_END_DECLS
return compose_file_dir;
}
+static int
+gtk_compose_table_find (gconstpointer data1,
+ gconstpointer data2)
+{
+ const GtkComposeTable *compose_table = (const GtkComposeTable *) data1;
+ guint32 hash = (guint32) GPOINTER_TO_INT (data2);
+ return compose_table->id != hash;
+}
+
+static void
+add_compose_table_from_file (const char *compose_file)
+{
+ guint hash;
+
+ G_LOCK (global_tables);
+
+ hash = g_str_hash (compose_file);
+ if (!g_slist_find_custom (global_tables, GINT_TO_POINTER (hash), gtk_compose_table_find))
+ {
+ GtkComposeTable *table;
+
+ table = gtk_compose_table_new_with_file (compose_file);
+
+ if (table)
+ global_tables = g_slist_prepend (global_tables, table);
+ }
+
+ G_UNLOCK (global_tables);
+}
+
+static void
+add_compose_table_from_data (const guint16 *data,
+ int max_seq_len,
+ int n_seqs)
+{
+ guint hash;
+
+ G_LOCK (global_tables);
+
+ hash = gtk_compose_table_data_hash (data, max_seq_len, n_seqs);
+ if (!g_slist_find_custom (global_tables, GINT_TO_POINTER (hash), gtk_compose_table_find))
+ {
+ GtkComposeTable *table;
+
+ table = gtk_compose_table_new_with_data (data, max_seq_len, n_seqs);
+
+ if (table)
+ global_tables = g_slist_prepend (global_tables, table);
+ }
+
+ G_UNLOCK (global_tables);
+}
+
static void
gtk_im_context_simple_init_compose_table (void)
{
path = g_build_filename (g_get_user_config_dir (), "gtk-4.0", "Compose", NULL);
if (g_file_test (path, G_FILE_TEST_EXISTS))
{
- G_LOCK (global_tables);
- global_tables = gtk_compose_table_list_add_file (global_tables, path);
- G_UNLOCK (global_tables);
-
+ add_compose_table_from_file (path);
g_free (path);
return;
}
path = g_build_filename (home, ".XCompose", NULL);
if (g_file_test (path, G_FILE_TEST_EXISTS))
{
- G_LOCK (global_tables);
- global_tables = gtk_compose_table_list_add_file (global_tables, path);
- G_UNLOCK (global_tables);
+ add_compose_table_from_file (path);
g_free (path);
return;
}
g_strfreev (langs);
if (path != NULL)
- {
- G_LOCK (global_tables);
- global_tables = gtk_compose_table_list_add_file (global_tables, path);
- G_UNLOCK (global_tables);
- }
- g_clear_pointer (&path, g_free);
+ add_compose_table_from_file (path);
+
+ g_free (path);
}
static void
int max_seq_len,
int n_seqs)
{
- g_return_if_fail (GTK_IS_IM_CONTEXT_SIMPLE (context_simple));
-
- G_LOCK (global_tables);
+ GtkComposeTable *table;
- global_tables = gtk_compose_table_list_add_array (global_tables,
- data, max_seq_len, n_seqs);
+ g_return_if_fail (GTK_IS_IM_CONTEXT_SIMPLE (context_simple));
- G_UNLOCK (global_tables);
+ add_compose_table_from_data (data, max_seq_len, n_seqs);
}
/**
{
g_return_if_fail (GTK_IS_IM_CONTEXT_SIMPLE (context_simple));
- G_LOCK (global_tables);
-
- global_tables = gtk_compose_table_list_add_file (global_tables, compose_file);
-
- G_UNLOCK (global_tables);
+ add_compose_table_from_file (compose_file);
}
static void
generate_output (const char *file)
{
- GSList *tables = NULL;
GtkComposeTable *table;
char *output;
- tables = gtk_compose_table_list_add_file (tables, file);
- table = tables->data;
+ table = gtk_compose_table_new_with_file (file);
output = gtk_compose_table_print (table);
g_print ("%s", output);
compose_table_compare (gconstpointer data)
{
const char *basename = data;
- GSList *tables = NULL;
GtkComposeTable *table;
char *file;
char *expected;
file = g_build_filename (g_test_get_dir (G_TEST_DIST), "compose", basename, NULL);
expected = g_strconcat (file, ".expected", NULL);
- tables = gtk_compose_table_list_add_file (tables, file);
-
- g_assert_true (g_slist_length (tables) == 1);
-
- table = tables->data;
+ table = gtk_compose_table_new_with_file (file);
output = gtk_compose_table_print (table);
diff = diff_with_file (expected, output, -1, &error);
static void
compose_table_match (void)
{
- GSList *tables = NULL;
GtkComposeTable *table;
char *file;
guint16 buffer[8] = { 0, };
file = g_build_filename (g_test_get_dir (G_TEST_DIST), "compose", "match", NULL);
- tables = gtk_compose_table_list_add_file (tables, file);
-
- g_assert_true (g_slist_length (tables) == 1);
-
- table = tables->data;
+ table = gtk_compose_table_new_with_file (file);
buffer[0] = GDK_KEY_Multi_key;
buffer[1] = 0;